package net.mikoo.seals.api.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.avalon.framework.parameters.ParameterException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import net.mikoo.seals.api.model.BaseResponse;
import net.mikoo.seals.api.model.ResultType;
import net.mikoo.seals.api.model.party.IsFirstLoginRequest;
import net.mikoo.seals.api.model.party.IsFirstLoginResponse;
import net.mikoo.seals.api.model.party.PartyInfoResponse;
import net.mikoo.seals.api.model.party.ResetPasswordRequest;
import net.mikoo.seals.api.model.party.ResetPwdRequest;
import net.mikoo.seals.api.model.party.SearchRequest;
import net.mikoo.seals.api.model.party.SearchResponse;
import net.mikoo.seals.api.model.party.SetPortraitRequest;
import net.mikoo.seals.api.model.party.SetUserInfoRequest;
import net.mikoo.seals.api.utility.PartyUtility;
import net.mikoo.seals.biz.model.PartyType;
import net.mikoo.seals.biz.service.PartyServices;
import net.mikoo.seals.biz.service.PersonServices;
import net.mikoo.seals.biz.service.UserLoginServices;
import net.mikoo.seals.common.enums.GenderEnum;
import net.mikoo.seals.common.exception.DataNotFoundException;
import net.mikoo.seals.common.exception.ParametersException;
import net.mikoo.seals.model.Party;
import net.mikoo.seals.model.PartyQuery;
import net.mikoo.seals.model.Person;
import net.mikoo.seals.model.UserLogin;
import net.mikoo.seals.utils.DateUtil;

@Controller
public class PartyController {

	private static Logger logger = LoggerFactory.getLogger(PartyController.class);
	
	@Autowired
	private PartyServices partyServices;
	
	@Autowired
	private UserLoginServices userLoginServices;
	
	@Autowired
	private PersonServices personServices;
	
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	
	@RequestMapping("/party/search")
	@ResponseBody
	public SearchResponse search(SearchRequest request, HttpServletRequest httpRequest) {
		SearchResponse result = new SearchResponse();
		try {
			if(request == null) {
				throw new IllegalArgumentException("request");
			}
			
			Long companyId = PartyUtility.getCurrentPartyCompanyId(httpRequest);
			if(companyId == null) {
				throw new IllegalArgumentException("companyId");
			}
			
			PartyQuery partyQuery = new PartyQuery();
//			partyQuery.setUserLoginId(request.getLoginName());
			partyQuery.setSearchKey(request.getLoginName());
			partyQuery.setSearchType("NAME_OR_USERLOGINID");
			partyQuery.setCompanyId(companyId);
			partyQuery.setIsSystem(request.getIsSystem());
			List<Party> partyList = partyServices.getListByQuery(partyQuery);
			
			if(partyList != null && !partyList.isEmpty()) {
				result = SearchResponse.valueOf(partyList);
			}
			result.setResult(ResultType.SUCCESS.getValue());
		}catch(Exception e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
		}
		return result;
	}
	
	@RequestMapping("/party/info")
	@ResponseBody
	public PartyInfoResponse info(HttpServletRequest request) {
		PartyInfoResponse result = new PartyInfoResponse();
		try {
			
			Party currentParty = PartyUtility.getCurrentParty(request);
			if(currentParty == null) {
				throw new IllegalArgumentException("partyId");
			}
			
			Party party = partyServices.loadByPrimaryKey(currentParty.getPartyId());
			if(party == null || StringUtils.isBlank(party.getUserLoginId())) {
				throw new DataNotFoundException("party not found");
			}
			
			party.setCompany(currentParty.getCompany());
			
			PartyType partyType = partyServices.getPartyType(currentParty.getPartyId(), PartyUtility.getCurrentPartyCompanyId(request));
			if(party != null) {
				result = PartyInfoResponse.valueOf(party, partyType);
			}
			result.setResult(ResultType.SUCCESS.getValue());
		}catch(Exception e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
		}
		return result;
	}
	
	@RequestMapping("/user/setPwd")
	@ResponseBody
	public BaseResponse resetPwd(ResetPwdRequest resetPwdRequest, HttpServletRequest request) {
		BaseResponse result = new BaseResponse();
		try {
			
			if(resetPwdRequest == null) {
				throw new ParameterException("resetPwdRequest");
			}
			
			if(StringUtils.isBlank(resetPwdRequest.getOldPwd())) {
				throw new ParameterException("resetPwdRequest.OldPwd");
			}
			
			if(StringUtils.isBlank(resetPwdRequest.getNewPwd())) {
				throw new ParameterException("resetPwdRequest.NewPwd");
			}
			userLoginServices.changePassword(PartyUtility.getCurrentUserLoginId(request), resetPwdRequest.getOldPwd(), resetPwdRequest.getNewPwd());
			result.setResult(ResultType.SUCCESS.getValue());
		}catch(Exception e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
		}
		return result;
	}
	
	@RequestMapping("/party/resetPassword")
	@ResponseBody
	public BaseResponse resetPassword(ResetPasswordRequest request) {
		
		BaseResponse result = new BaseResponse();
		try {
			
			if(request == null) {
				throw new ParametersException("参数错误");
			}
			
			if(StringUtils.isBlank(request.getPhone())) {
				throw new ParametersException("用户账号不能为空");
			}
			
			if(StringUtils.isBlank(request.getPassword())) {
				throw new ParametersException("登陆密码不能为空");
			}
			final String SMS_DATETIME_FORMAT = "sms_code_datetime_%s";
			final String SMS_CODE_FORMAT = "sms_send_code_%s";
			final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
			
			String sendTimeStr = redisTemplate.opsForValue().get(String.format(SMS_DATETIME_FORMAT, request.getPhone()));
			if(StringUtils.isBlank(sendTimeStr)) {
				throw new ParametersException("短信验证码错误");
			}
			try {
				Date sendTime = DateUtil.stringToDate(sendTimeStr, DATETIME_FORMAT);
				if(sendTime == null || System.currentTimeMillis() - sendTime.getTime() > 5 * 60 * 1000) {
					throw new ParametersException("短信验证码过期");
				}
			}catch(Exception e) {
				throw new ParametersException("短信验证码错误");
			}
			
			String smsCode = redisTemplate.opsForValue().get(String.format(SMS_CODE_FORMAT, request.getPhone()));
			if(StringUtils.isBlank(smsCode) || !smsCode.equals(request.getSmsCode())) {
				throw new ParametersException("短信验证码错误");
			}
			userLoginServices.resetPassword(request.getPhone(), request.getPassword());
			result.setResult(ResultType.SUCCESS.getValue());
		}catch(ParametersException e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
			result.setErrorMsg(e.getMessage());
		}catch(Exception e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
			result.setErrorMsg("重置密码失败");
		}
		return result;
		
	}
	
	@RequestMapping("/user/logout")
	@ResponseBody
	public BaseResponse logout(HttpServletRequest request) {
		BaseResponse result = new BaseResponse();
		try {
			userLoginServices.wechatLogout(PartyUtility.getCurrentUserLoginId(request));
			result.setResult(ResultType.SUCCESS.getValue());
		}catch(Exception e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
		}
		return result;
	}
	
	@RequestMapping("/user/setPortrait")
	@ResponseBody
	public BaseResponse setPortrait(SetPortraitRequest setPortraitRequest, HttpServletRequest request) {
		BaseResponse result = new BaseResponse();
		try {
			
			if(setPortraitRequest == null) {
				throw new ParameterException("setPortraitRequest");
			}
			
			if(StringUtils.isBlank(setPortraitRequest.getImgUrl())) {
				throw new ParameterException("setPortraitRequest.imgUrl");
			}
			
			personServices.modifyPortrait(PartyUtility.getCurrentPartyId(request), setPortraitRequest.getImgUrl());
			result.setResult(ResultType.SUCCESS.getValue());
		}catch(Exception e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
		}
		return result;
	}
	
	@RequestMapping("/user/setInfo")
	@ResponseBody
	public BaseResponse serInfo(SetUserInfoRequest request, HttpServletRequest httpRequest) {
		BaseResponse result = new BaseResponse();
		try {
			
			if(StringUtils.isBlank(request.getName())) {
				throw new ParameterException("name is null");
			}
			
			Person person = new Person();
			person.setPartyId(PartyUtility.getCurrentPartyId(httpRequest));
			person.setName(request.getName());
			person.setMobile(request.getMobile());
			
			GenderEnum gender = GenderEnum.getByCode(request.getGender());
			if(gender != null) {
				person.setGender(request.getGender());
			}
			person.setEmail(request.getEmail());
			
			personServices.modifyByPrimaryKey(person);
			result.setResult(ResultType.SUCCESS.getValue());
		}catch(Exception e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
		}
		return result;
	}
	
	
	@RequestMapping("/user/isFirstLogin")
	@ResponseBody
	public IsFirstLoginResponse isFirstLogin(IsFirstLoginRequest request) {
		IsFirstLoginResponse result = new IsFirstLoginResponse();
		try {
			
			if(request == null) {
				throw new IllegalArgumentException("request");
			}
			
			if(StringUtils.isBlank(request.getUserName())) {
				throw new IllegalArgumentException("request.userName");
			}
			
			UserLogin userlogin = userLoginServices.loadByPrimaryKey(request.getUserName());
			if(userlogin != null && userlogin.getLastLoginTime() == null) {
				result.setIsFirstLogin("Y");
			}else {
				result.setIsFirstLogin("N");
			}
			result.setResult(ResultType.SUCCESS.getValue());
		}catch(Exception e) {
			logger.error("", e);
			result.setResult(ResultType.ERROR.getValue());
		}
		return result;
	}
	
}
